致远OA rest接口重置密码漏洞分析

复现环境

致远 V7.1SP1

补丁分析

致远官方在2023年8月发布了rest接口重置密码漏洞补丁,补丁链接https://service.seeyon.com/patchtools/tp.html#/patchList?type=%E5%AE%89%E5%85%A8%E8%A1%A5%E4%B8%81&id=175

image-20240219151815705
image-20240219152726184

致远是通过jersey框架实现REST接口,通过配置init-param参数来添加过滤器类,添加后,在进入到资源类之前,会先进入到过滤器类,一些校验的逻辑就可以写在过滤器中。

image-20240219152917793

rest接口重置密码漏洞补丁的工作原理是通过将用户角色权限与资源访问权限的逻辑写在ResourceCheckRoleAccessFilter类中,在ResourceCheckRoleAccessFilterfilter方法中,会以访问资源类的类名及方法名和当前用户作为参数调用RestCheckRoleAccessManagerImplcheckRole方法,验证当前用户是否具有访问资源类的权限,如果不具备访问权限,则抛出异常。

image-20240219153710590

在补丁包中checkRoleAccessInfo.properties配置文件中,定义了com.seeyon.ctp.rest.resources.MemberResource类中方法已经对应的用户访问权限。

image-20240219154701136

MemberResource.classchangePassword方法中,可通过指定memberidpassword对用户密码进行修改。

image-20240219155143070

致远中存在一些自带的用户,这些用户的memberid值都是固定的,正常情况下,我们可以通过changePassword方法修改system等用户的密码。

image-20240219155523647
1
2
3
4
seeyon-guest -6964000252392685202
system -7273032013234748168
audit-admin -4401606663639775639
group-admin 5725175934914479521

rest接口权限校验

CTPSecurityFilter.classdoFilter方法中,根据uri的特征,分别有7种权限校验的方法。

image-20240219160122332
image-20240219160159183

uri的前缀为/seeyon/rest/时,会调用RestAuthenticator.classauthenticate方法进行验证,该接口仅支持token进行认证,不允许使用Session

image-20240219160650029

在致远的开放平台描述了toekn的获得方式,https://open.seeyon.com/book/ctp/restjie-kou/gai-shu.html

image-20240219161108194

两个步骤,1、登录系统用户创建一个rest用户,

image-20240219161633183

2、通过/seeyon/rest/token/{restusername}/{password}接口获取token

image-20240219161705630

获取到token以后,就可以调用changePassword方法修改密码了,调用路径/seeyon/rest/orgMember/{id}/password/{password},这里将system用户密码修改为123456

image-20240219162037736

通过system管理员创建rest用户,在通过rest用户获取token,最后通过token访问接口修改密码,利用的前提需要一个管理员账号,难免有些鸡肋。而访问rest接口只能是token,而token只能通过管理员创建rest用户拿到,看起来是个死结,实际上大佬们的思路是另辟蹊径。

权限绕过

回到CTPSecurityFilter.classdoFilter方法中,在进入到rest接口的权限校验方法前,会先判断是不是SpringController的请求。

image-20240219164914490

uri的后缀为.do或者 .do;jessionid=的时候,那么就会进入到SpringControllerAuthenticatorauthenticate方法中进行验证。

image-20240219165048320

而rest接口修改密码的路由为/seeyon/rest/orgMember/-7273032013234748168/password/123456123456为我们需要修改的密码,当把密码写成123456.do或者123456.do;jessionid= ,即可让该请求走SpringControllerAuthenticatorauthenticate方法中进行验证,所以只需要普通用户的权限就可以修改管理员的密码。

image-20240219170001383

武器化利用思考

致远中存在一些接口,是可以RCE的,但是设置了访问权限,当拿到管理员权限以后,我们可以通过管理员权限为普通用户赋予一些访问权限,然后调用这些接口实现RCE,另一个是通过管理员权限创建普通用户留后门。

修复

在致远 8.2之后版本的CTPSecurityFilter.class中,除验证uri路径以.do结尾以外,还验证了该uri是否为rest接口,限制了普通用户禁止通过SpringController的验证逻辑去访问rest接口。

image-20240219151246181